import type { SelectProps } from "antd/lib/select"
import styles from "./index.module.less"
import { Select } from "antd"
import { useState, useEffect } from "react";

export interface RemoteSelectProps {
  request: (params: Record<string, any>) => Promise<{ 
    data: { label: string; value: string | number }[],
    total?: number,
    hasMore?: boolean
  }>
  onChange?: (value: string | number | (string | number)[]) => void
  debounceTime?: number
  pageSize?: number
  antdSelectProps?: Omit<SelectProps, 'options' | 'showSearch' | 'onSearch' | 'onPopupScroll' | "onchange">
}

const debouncFunc = (func: (...args: any[]) => void, wait: number) => {
  let timeout: any = null;
  return (...args: any[]) => {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(() => {
      func(...args);
    }, wait);
  }
}

const RemoteSelect = (props: RemoteSelectProps) => {
  const { debounceTime = 300, pageSize = 10 } = props;
  const [options, setOptions] = useState<{ label: string; value: string | number }[]>([])
  const [loading, setLoading] = useState(false);
  const [searchValue, setSearchValue] = useState<string>('');
  const [pagination, setPagination] = useState({
    current: 1,
    pageSize,
    total: 0,
    hasMore: true
  });

  const resetPagination = () => {
    setPagination({
      current: 1,
      pageSize,
      total: 0,
      hasMore: true
    });
  };

  useEffect(() => {
    remoteFetch({ current: 1 });
  }, [props.request]);

  const remoteFetch = async (params: Record<string, any> = {}) => {
    if (!props.request) return;
    
    setLoading(true);
    try {
      const { keyword, ...restParams } = params;
      const reqParams: Record<string, any> = {
        current: pagination.current,
        pageSize: pagination.pageSize,
        ...restParams
      };
      
      if (keyword !== undefined) {
        reqParams.keyword = keyword;
      } else if (searchValue) {
        reqParams.keyword = searchValue;
      }

      const response = await props.request(reqParams);
      
      if (params.current === 1) {
        setOptions(response.data);
      } else {
        setOptions((prev) => [...prev, ...response.data]);
      }
      
      setPagination((prev) => ({
        ...prev,
        current: params.current || prev.current,
        total: response.total || 0,
        hasMore: response.hasMore !== undefined ? response.hasMore : 
                (response.total ? prev.current * prev.pageSize < response.total : false)
      }));
    } finally {
      setLoading(false);
    }
  };

  const handleSearch = debouncFunc((value: string) => {
    setSearchValue(value);
    resetPagination();
    remoteFetch({ keyword: value, current: 1 });
  }, debounceTime);

  const handlePopupScroll = (e: React.UIEvent<HTMLDivElement>) => {
    const target = e.target as HTMLDivElement;
    if (
      !loading &&
      pagination.hasMore &&
      target.scrollTop + target.clientHeight >= target.scrollHeight - 10
    ) {
      const nextPage = pagination.current + 1;
      setPagination((prev) => ({
        ...prev,
        current: nextPage
      }));
      remoteFetch({ current: nextPage });
    }
  };

  return (
    <div className={styles.wrapper}>
      <Select 
        {...props.antdSelectProps}
        showSearch
        onChange={props.onChange}
        options={options}
        filterOption={false}
        loading={loading}
        onSearch={handleSearch}
        onPopupScroll={handlePopupScroll}
        notFoundContent={loading ? '加载中...' : (options.length === 0 ? '无数据' : null)}
      />
    </div>
  )
}

export default RemoteSelect